/*
* This file is part of RoboDS (http://code.google.com/p/robods/)
* Copyright (C) 2007 Blakharaz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* 
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
* 
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
*/

#include "DsGame.h"

#include <string>

#include "DsAutomaticEffectsState.h"
#include "DsCard.h"
#include "DsLogger.h"
#include "DsMap.h"
#include "DsMoveRobotsState.h"
#include "DsPrepareRoundState.h"
#include "DsRobot.h"
#include "DsUserInputState.h"
#include "DsUserInterface.h"
#include "SpriteManager.h"

//#include "BnsClient.h"
//#include "Card.h"


using namespace std;

namespace robo
{

    const char* createTestMap()
    {
        std::string map;
        /*      1234567890*/
        map += "          "; // 1
        map += " OO       "; // 2
        map += " OO       "; // 3
        map += "          "; // 4
        map += "  rbb     "; // 5
        map += "  r       "; // 6
        map += "  rtt     "; // 7
        map += "          "; // 8

        return map.c_str();
    }

    void handletiletest()
    {
	    static int tilenum = 0;
	    static Logger* logger = Logger::getSingleton();

	    if (Pad.Released.A)
	    {
		    tilenum--;
		    if (tilenum < 0)
		    {
			    tilenum = 0;
		    }
		    char buf[30];
		    sprintf(buf, "Tile %d", tilenum);
		    logger->log(buf);
		    PA_SetLargeMapTile(1, SpriteManager::BACKGROUND_MAP, 3, 18, tilenum);
	    }
	    if (Pad.Released.B)
	    {
		    tilenum++;
		    char buf[30];
		    sprintf(buf, "Tile %d", tilenum);
		    logger->log(buf);
		    PA_SetLargeMapTile(1, SpriteManager::BACKGROUND_MAP, 3, 18, tilenum);
	    }
    }

    //int main_wlan()
    //{
	   // PA_Init();
	   // PA_InitVBL();

	   // PA_InitWifi();
	   // PA_ConnectWifiWFC();

	   // BnsClient* bns = new BnsClient();
	   // bns->connect("", 0);
	   // bns->setPlayerName("FooBarSpam");

    //    return 0;
    //}

    DsGame::DsGame()
        : Game()
    {
    }

    DsGame::~DsGame()
    {
    }

    void DsGame::initialize()
    {
        PA_Init();
	    PA_InitVBL();

	    PA_SetVideoMode(0, 2);  //screen, mode
	    PA_SetVideoMode(1, 1);  //screen, mode
	    PA_InitText(1, 0);

        Logger* logger = new DsLogger();
	    logger->log("Start");

        Map* testmap = new DsMap(10, 8);
        testmap->load(createTestMap());
        Robot* testrobot = new DsRobot(1, DsSprite::SPRITE_BOT_1);
	    testrobot->setMapPosition(0, 0);

        DsUserInterface* ui = new DsUserInterface(testrobot);
        ui->setMap(testmap);

	    setCurrentState(GameState::PREPARE_ROUND);

       	mUserInputState = new DsUserInputState(this, ui);
	    mMoveRobotsState = new DsMoveRobotsState(this);
	    mMoveRobotsState->addController(ui);
	    mPrepareRoundState = new DsPrepareRoundState(this);
	    mPrepareRoundState->addController(ui);
	    mAutomaticEffectsState = new DsAutomaticEffectsState(this, ui);
	    mAutomaticEffectsState->addController(ui);
    }

    void DsGame::run()
    {
        // Infinite game loop
	    while (true)
	    {
		    // BEGIN Tile test code
		    //handletiletest();
		    // END Tile test code

            mCurrentState->handleEvents();
		    PA_WaitForVBL();
	    }
    }

    void DsGame::destroy()
    {
        // NDS games run forever
    }

    void DsGame::stateChanged(GameState::StateType oldState, GameState::StateType newState)
    {
    }

    Card* DsGame::createCard(Card::CardType type, int priority)
    {
        return new DsCard(type, priority, 
            SpriteManager::getSingleton()->getCardSprite(type));
    }
    
    AbstractJob* DsGame::createMovementJob(Robot* robot, Vector2 start, Vector2 target, int frames)
    {
        return NULL;
    }
    
    AbstractJob* DsGame::createTurnJob(Robot* robot, Card::CardType type, int frames)
    {
        return NULL;
    }
}
